package com.imooc.aspect;

import io.seata.core.context.RootContext;
import io.seata.core.exception.TransactionException;
import io.seata.tm.api.GlobalTransaction;
import io.seata.tm.api.GlobalTransactionContext;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Before;

/**
 * 分布式事务,如果被调用方发生异常，而项目中统一异常处理中处理了这个异常，
 * 会导致全局事务失效;
 * 所以用aop的方式去手动回滚全局事务
 * @author liansen
 * @create 03-10-19:37
 */
//@Aspect
//@Component
public class SeataAspect {


    /**
     *
     * 调用service之前，手动加入或者创建全局事务
     * @param joinPoint
     * @throws TransactionException
     */
    @Before("execution(* com.imooc.service.impl..*.*(..))")
    public void beginTransaction(JoinPoint joinPoint) throws TransactionException {
        //手动开启全局事务
        GlobalTransaction gt = GlobalTransactionContext.getCurrentOrCreate();
        gt.begin();
    }


    @AfterThrowing(
            pointcut ="execution(* com.imooc.service.impl..*.*(..))",
            throwing = "throwable"
    )
    public void seataRollback(Throwable throwable) throws TransactionException {
        String xid = RootContext.getXID();
        if(StringUtils.isNotBlank(xid)){
            GlobalTransactionContext.reload(xid).rollback();
        }
    }
}
